import { ENGINE_HOOKS } from "@dendronhq/engine-test-utils";
import path from "path";
import sinon from "sinon";
import * as vscode from "vscode";
import {
  InstrumentedWrapperCommand,
  InstrumentedWrapperCommandArgs,
} from "../../commands/InstrumentedWrapperCommand";
import { ExtensionProvider } from "../../ExtensionProvider";
import { AnalyticsUtils } from "../../utils/analytics";
import { VSCodeUtils } from "../../vsCodeUtils";
import { expect } from "../testUtilsv2";
import { describeMultiWS } from "../testUtilsV3";

suite("GIVEN a InstrumentedWrapperCommand", function () {
  describeMultiWS(
    "WHEN a Command instance is generated by InstrumentedWrapperCommand.createVSCodeCommand",
    {
      preSetupHook: ENGINE_HOOKS.setupBasic,
    },
    () => {
      test("THEN the returned command is executable by vscode.commands.executeCommand", async () => {
        const { wsRoot, vaults } = ExtensionProvider.getDWorkspace();

        const fooPath = path.join(wsRoot, vaults[0].fsPath, "foo.md");
        const commandArgs: InstrumentedWrapperCommandArgs = {
          command: {
            title: "Test Open Command Wrapper",
            command: "vscode.open",
            arguments: [vscode.Uri.file(fooPath)],
          },
          event: "TestEvent",
        };

        const result =
          InstrumentedWrapperCommand.createVSCodeCommand(commandArgs);

        await vscode.commands.executeCommand(
          result.command,
          ...result.arguments!
        );

        const activeEditor = VSCodeUtils.getActiveTextEditor();
        expect(activeEditor?.document.fileName).toEqual(fooPath);
      });
    }
  );

  describeMultiWS(
    "WHEN a wrapper command is run",
    {
      preSetupHook: ENGINE_HOOKS.setupBasic,
    },
    () => {
      test("THEN the inner command is executed and a telemetry point is fired", async () => {
        const TEST_EVENT = "TestEvent";
        const analyticsStub = sinon.stub(AnalyticsUtils, "track");

        const { wsRoot, vaults } = ExtensionProvider.getDWorkspace();

        const fooPath = path.join(wsRoot, vaults[0].fsPath, "foo.md");
        const commandArgs: InstrumentedWrapperCommandArgs = {
          command: {
            title: "Test Open Command Wrapper",
            command: "vscode.open",
            arguments: [vscode.Uri.file(fooPath)],
          },
          event: TEST_EVENT,
        };

        const cmd = new InstrumentedWrapperCommand();
        await cmd.run(commandArgs);

        const activeEditor = VSCodeUtils.getActiveTextEditor();
        expect(activeEditor?.document.fileName).toEqual(fooPath);

        let telemetrySentCount = 0;

        analyticsStub.getCalls().forEach((call) => {
          if (TEST_EVENT === call.firstArg) {
            telemetrySentCount += 1;
          }
        });

        expect(telemetrySentCount).toEqual(1);
        analyticsStub.restore();
      });
    }
  );
});
